package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.account.client.UserAccountFeignClient;
import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.order.OrderDerate;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.model.payment.PaymentInfo;
import com.atguigu.tingshu.model.user.VipServiceConfig;
import com.atguigu.tingshu.order.helper.SignHelper;
import com.atguigu.tingshu.order.mapper.OrderDerateMapper;
import com.atguigu.tingshu.order.mapper.OrderDetailMapper;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderDetailService;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.client.VipServiceConfigFeignClient;
import com.atguigu.tingshu.vo.account.AccountDeductVo;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.atguigu.tingshu.vo.order.OrderDerateVo;
import com.atguigu.tingshu.vo.order.OrderDetailVo;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Autowired
    private AlbumInfoFeignClient albumInfoFeignClient;

    @Autowired
    private VipServiceConfigFeignClient vipServiceConfigFeignClient;

    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @Autowired
    private KafkaService kafkaService;

    @Autowired
    private UserAccountFeignClient userAccountFeignClient;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderDerateMapper orderDerateMapper;


    @Override
    public IPage<OrderInfo> findUserPage(Page<OrderInfo> orderInfoPage, Long userId, String orderStatus) {
        //  多表关联查询! orderInfo orderDetail
        IPage<OrderInfo> orderInfoIPage = orderInfoMapper.selectUserPage(orderInfoPage, userId, orderStatus);
        orderInfoIPage.getRecords().forEach(orderInfo -> {
            orderInfo.setPayWayName(orderInfo.getPayWay().equals(SystemConstant.ORDER_PAY_ACCOUNT) ? "余额" : "微信");
            orderInfo.setOrderStatusName(this.getOrderStatusNameByOrderStatus(orderInfo.getOrderStatus()));
        });
        //  返回数据
        return orderInfoIPage;
    }

    private String getOrderStatusNameByOrderStatus(String orderStatus) {
        //  声明变量
        String orderStatusName = "";
        if (orderStatus.equals(SystemConstant.ORDER_STATUS_UNPAID)) {
            orderStatusName = "未支付";
        } else if (orderStatus.equals(SystemConstant.ORDER_STATUS_PAID)) {
            orderStatusName = "已支付";
        } else {
            orderStatusName = "已取消";
        }
        return orderStatusName;
    }


    @Override
    public void orderCancel(String orderId) {
        //  修改状态.
        OrderInfo orderInfo = this.getById(orderId);
        //  判断状态
        if (null != orderInfo && orderInfo.getOrderStatus().equals(SystemConstant.ORDER_STATUS_UNPAID)) {
            orderInfo.setId(Long.parseLong(orderId));
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_CANCEL);
            //  返回执行结果
            int result = orderInfoMapper.updateById(orderInfo);
            if (result > 0) {
                //  如果有交易记录，应该取消.
                //  PaymentInfoFeignClient.closePayment(orderInfo.getOrderNo());
                this.kafkaService.sendMsg(KafkaConstant.QUEUE_PAYMENT_CANCEL, orderInfo.getOrderNo());
            }
        }
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public String submitOrder(OrderInfoVo orderInfoVo, Long userId) {
        //  1.  校验签名: 订单结算页设置了签名.
        Map map = JSON.parseObject(JSON.toJSONString(orderInfoVo), Map.class);
        map.put("payWay", "");
        //  调用校验签名方法.
        SignHelper.checkSign(map);
        //  2.  防止重复提交订单。
        String tradeNo = orderInfoVo.getTradeNo();
        //  redis : 必须有key
        String tradeNoKey = "user:trade:" + userId;
        //  保证删除具有原子性. key与键值一致！
        String scriptText = "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" +
                "then\n" +
                "    return redis.call(\"del\",KEYS[1])\n" +
                "else\n" +
                "    return 0\n" +
                "end";
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(scriptText);
        redisScript.setResultType(Long.class);
        //  执行lua脚本:
        Long count = (Long) this.redisTemplate.execute(redisScript, Arrays.asList(tradeNoKey), tradeNo);
        //  判断受影响的行数
        if (count == 0) {
            throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
        }
        //  生成一个订单号：
        String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
        //  判断支付方式：
        if (orderInfoVo.getPayWay().equals(SystemConstant.ORDER_PAY_WAY_WEIXIN)) {
            //  微信
            this.saveOrder(orderInfoVo, userId, orderNo);
            //  返回订单编号
            return orderNo;
        } else {
            try {
                //  检查与扣减对象
                AccountDeductVo accountDeductVo = new AccountDeductVo();
                accountDeductVo.setOrderNo(orderNo);
                accountDeductVo.setUserId(userId);
                accountDeductVo.setAmount(orderInfoVo.getOrderAmount());
                //  锁定内容.
                accountDeductVo.setContent(orderInfoVo.getItemType());
                //  service-account: 检查与锁定
                //  Result<AccountLockResultVo> result = userAccountFeignClient.checkAndLock(accountLockVo);
                Result result = userAccountFeignClient.checkAndDeduct(accountDeductVo);
                //  判断
                if (200 != result.getCode()) {
                    throw new GuiguException(result.getCode(), result.getMessage());
                }
                //  调用保存订单方法
                OrderInfo orderInfo = this.saveOrder(orderInfoVo, userId, orderNo);
                //  创建用户购买记录对象
                UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
                //  记录用户购买信息
                userPaidRecordVo.setOrderNo(orderNo);
                userPaidRecordVo.setUserId(orderInfo.getUserId());
                userPaidRecordVo.setItemType(orderInfo.getItemType());
                //  购买项目的Id 专辑Id，声音Id, 服务配置Id: 在哪? order_detail.item_id
                //  List<Long> itemIdList = orderInfo.getOrderDetailList().stream().map(OrderDetail::getItemId).collect(Collectors.toList());
                List<Long> itemIdList = orderInfoVo.getOrderDetailVoList().stream().map(OrderDetailVo::getItemId).collect(Collectors.toList());
                userPaidRecordVo.setItemIdList(itemIdList);
                //  远程调用：
                Result userResult = userInfoFeignClient.savePaidRecord(userPaidRecordVo);
                //  判断
                if (200 != userResult.getCode()) {
                    throw new GuiguException(211, "新增购买记录异常");
                }
                //  发送消息.
                //  this.kafkaService.sendMsg(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));
                //  扣减金额：变成了异步操作。
                //  kafkaService.sendMsg(KafkaConstant.QUEUE_ACCOUNT_MINUS, orderNo);
                //  返回订单编号
                return orderNo;
            } catch (GuiguException e) {
                //  解锁金额：
                //  kafkaService.sendMsg(KafkaConstant.QUEUE_ACCOUNT_UNLOCK, orderNo);
                //  e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
        }
    }

    /**
     * 保存订单：
     *
     * @param orderInfoVo
     * @param userId
     * @param orderNo
     */
    @Transactional(rollbackFor = Exception.class)
    public OrderInfo saveOrder(OrderInfoVo orderInfoVo, Long userId, String orderNo) {
        //  保存数据：order_info order_detail order_derate
        OrderInfo orderInfo = new OrderInfo();
        //  赋值：属性拷贝
        BeanUtils.copyProperties(orderInfoVo, orderInfo);
        //  赋值用户Id
        orderInfo.setUserId(userId);
        orderInfo.setOrderTitle(orderInfoVo.getOrderDetailVoList().get(0).getItemName());
        orderInfo.setOrderNo(orderNo);
        orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_UNPAID);
        //  保存数据.
        this.save(orderInfo);

        //  order_detail
        List<OrderDetailVo> orderDetailVoList = orderInfoVo.getOrderDetailVoList();
        if (!CollectionUtils.isEmpty(orderDetailVoList)) {
            //  循环插入 购买声音 item_id = track_id 购买vip item_id=vip_service_config.id 购买专辑 item_id = album_Id;
            orderDetailVoList.stream().forEach(orderDetailVo -> {
                //  创建对象
                OrderDetail orderDetail = new OrderDetail();
                //  属性拷贝.
                BeanUtils.copyProperties(orderDetailVo, orderDetail);
                orderDetail.setOrderId(orderInfo.getId());
                orderDetailMapper.insert(orderDetail);
            });

            //  减免：
            List<OrderDerateVo> orderDerateVoList = orderInfoVo.getOrderDerateVoList();
            if (!CollectionUtils.isEmpty(orderDerateVoList)) {
                //  循环遍历。
                orderDerateVoList.stream().forEach(orderDerateVo -> {
                    //  创建对象
                    OrderDerate orderDerate = new OrderDerate();
                    //  属性拷贝.
                    BeanUtils.copyProperties(orderDerateVo, orderDerate);
                    orderDerate.setOrderId(orderInfo.getId());
                    orderDerateMapper.insert(orderDerate);
                });
            }
        }
        //  判断支付方式：
        if (orderInfoVo.getPayWay().equals(SystemConstant.ORDER_PAY_ACCOUNT)) {
            //  余额： 支付成功.---> 支付成功的业务处理. 改状态--记录当前购买记录
            this.orderPaySuccess(orderNo);
        } else {
            //  微信：kafka不支持延迟消息发送：RedissonClient;取消订单。
            this.sendDelayMessage(orderInfo.getId());
        }
        //  orderInfo.setOrderDetailList();
        //  返回订单对象
        return orderInfo;
    }

    private void sendDelayMessage(Long orderId) {
        //  阻塞队列
        RBlockingQueue<Object> blockingQueue = redissonClient.getBlockingQueue(KafkaConstant.QUEUE_ORDER_CANCEL);
        //  变成延迟
        RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
        //  发送数据. 过5分钟才会发送数据。
        delayedQueue.offer(orderId.toString(), KafkaConstant.DELAY_TIME, TimeUnit.SECONDS);

    }

    /**
     * 支付成功。修改订单记录.记录购买信息.
     *
     * @param orderNo
     */
    @Override
    public void orderPaySuccess(String orderNo) {
        //  1. 查询什么? orderInfo? order_status=? where order_no = ?;
        //  OrderInfo orderInfo = this.orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        OrderInfo orderInfo = this.getOrderInfoByOrderNo(orderNo);
        //  判断当前订单状态。
        if (orderInfo.getOrderStatus().equals(SystemConstant.ORDER_STATUS_UNPAID)) {
            //  赋值：
            orderInfo.setOrderStatus(SystemConstant.ORDER_STATUS_PAID);
            //  修改订单状态.
            this.orderInfoMapper.updateById(orderInfo);
        }
        //  判断
        //        UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
        //        userPaidRecordVo.setOrderNo(orderNo);
        //        userPaidRecordVo.setUserId(orderInfo.getUserId());
        //        userPaidRecordVo.setItemType(orderInfo.getItemType());
        //        //  购买项目的Id 专辑Id，声音Id, 服务配置Id: 在哪? order_detail.item_id
        //        List<Long> itemIdList = orderInfo.getOrderDetailList().stream().map(OrderDetail::getItemId).collect(Collectors.toList());
        //        userPaidRecordVo.setItemIdList(itemIdList);
        //        //  发送消息.
        //        this.kafkaService.sendMsg(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));
    }

    @Override
    public OrderInfo getOrderInfoByOrderNo(String orderNo) {
        //  查询订单主表信息.
        OrderInfo orderInfo = this.orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
        //  在查询订单明细.
        if (null != orderInfo) {
            List<OrderDetail> orderDetailList = orderDetailMapper.selectList(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderInfo.getId()));
            orderInfo.setOrderDetailList(orderDetailList);
        }
        //  支付方式名称赋值.
        orderInfo.setPayWayName(orderInfo.getPayWay().equals(SystemConstant.ORDER_PAY_ACCOUNT) ? "余额" : "微信");
        //  返回数据。
        return orderInfo;
    }

    @Override
    public OrderInfoVo trade(TradeVo tradeVo, Long userId) {
        //  订单原始金额
        BigDecimal originalAmount = new BigDecimal("0.00");
        //  订单减免金额
        BigDecimal derateAmount = new BigDecimal("0.00");
        //  订单实际金额
        BigDecimal orderAmount = new BigDecimal("0.00");
        //  订单明细
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        //  减免明细
        List<OrderDerateVo> orderDerateVoList = new ArrayList<>();

        //  判断 购买专辑
        if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)) {
            //  购买专辑 判断用户是否购买过专辑. user_paid_album
            Result<Boolean> booleanResult = userInfoFeignClient.isPaidAlbum(tradeVo.getItemId());
            Assert.notNull(booleanResult, "购买专辑返回结果集为空");
            Boolean flag = booleanResult.getData();
            Assert.notNull(flag, "购买专辑返回结果为空");
            if (flag) {
                //  抛出异常
                throw new GuiguException(ResultCodeEnum.REPEAT_BUY_ERROR);
            }
            //  用户没有购买过专辑. 计算当前购买专辑的价格
            Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
            Assert.notNull(userInfoVoResult, "获取用户信息返回结果集为空");
            UserInfoVo userInfoVo = userInfoVoResult.getData();
            Assert.notNull(userInfoVo, "用户信息为空");

            //  获取到专辑信息
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(tradeVo.getItemId());
            Assert.notNull(albumInfoResult, "获取专辑信息返回结果集为空");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "专辑信息为空");
            //  原始金额
            originalAmount = albumInfo.getPrice();
            //  判断是否有折扣信息.
            if (albumInfo.getVipDiscount().intValue() != -1) {
                //  身份判断 vip
                if (userInfoVo.getIsVip() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
                    //  计算vip的折扣价格. total=1000 8; 800; 200; 1000*(10-8)=200
                    derateAmount = originalAmount.multiply(new BigDecimal("10").subtract(albumInfo.getVipDiscount())).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                }
            }
            //  普通用户
            if (albumInfo.getDiscount().intValue() != -1) {
                if (userInfoVo.getIsVip() == 0) {
                    //  计算vip的折扣价格. total=1000 8; 800; 200; 1000*(10-8)=200
                    derateAmount = originalAmount.multiply(new BigDecimal("10").subtract(albumInfo.getDiscount())).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
                }
            }
            //  订单实际金额
            orderAmount = originalAmount.subtract(derateAmount);
            //  计算订单明细：
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            orderDetailVo.setItemPrice(orderAmount);
            orderDetailVo.setItemName(albumInfo.getAlbumTitle());
            orderDetailVo.setItemUrl(albumInfo.getCoverUrl());
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVoList.add(orderDetailVo);
            //  计算减免明细：
            //  判断
            if (derateAmount.compareTo(BigDecimal.ZERO) != 0) {
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_ALBUM_DISCOUNT);
                orderDerateVoList.add(orderDerateVo);
            }

        } else if (tradeVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)) {
            //  购买声音TradeVo
            if (tradeVo.getTrackCount() < 0) {
                throw new GuiguException(ResultCodeEnum.ARGUMENT_VALID_ERROR);
            }
            //  获取声音列表
            Result<List<TrackInfo>> trackInfoListResult = trackInfoFeignClient.findPaidTrackInfoList(tradeVo.getItemId(), tradeVo.getTrackCount());
            Assert.notNull(trackInfoListResult, "购买声音列表结果集为空");
            List<TrackInfo> trackInfoList = trackInfoListResult.getData();
            Assert.notNull(trackInfoList, "购买声音列表为空");
            //  根据声音Id 获取到专辑对象 == trackInfoList集合中获取专辑Id
            Long albumId = trackInfoList.get(0).getAlbumId();
            Result<AlbumInfo> albumInfoResult = albumInfoFeignClient.getAlbumInfo(albumId);
            Assert.notNull(albumInfoResult, "获取专辑信息返回结果集为空");
            AlbumInfo albumInfo = albumInfoResult.getData();
            Assert.notNull(albumInfo, "专辑信息为空");
            //  计算购买金额 price*tradeVo.getTrackCount
            originalAmount = tradeVo.getTrackCount().intValue() != 0 ? albumInfo.getPrice().multiply(new BigDecimal(tradeVo.getTrackCount().toString())) : albumInfo.getPrice();
            orderAmount = originalAmount;
            //  赋值订单明细. 没有减免
            orderDetailVoList = trackInfoList.stream().map(trackInfo -> {
                //  创建对象
                OrderDetailVo orderDetailVo = new OrderDetailVo();
                //  赋值
                orderDetailVo.setItemId(trackInfo.getId());
                orderDetailVo.setItemPrice(albumInfo.getPrice());
                orderDetailVo.setItemUrl(trackInfo.getCoverUrl());
                orderDetailVo.setItemName(trackInfo.getTrackTitle());
                //  返回数据
                return orderDetailVo;
            }).collect(Collectors.toList());

        } else {
            //  购买vip tradeVo.getItemId():vip服务配置id
            Result<VipServiceConfig> vipServiceConfigResult = vipServiceConfigFeignClient.getVipServiceConfig(tradeVo.getItemId());
            Assert.notNull(vipServiceConfigResult, "vip服务配置信息结果集为空");
            VipServiceConfig vipServiceConfig = vipServiceConfigResult.getData();
            Assert.notNull(vipServiceConfig, "vip服务配置对象为空");
            //  订单原始金额
            originalAmount = vipServiceConfig.getPrice();
            //  实际金额
            orderAmount = vipServiceConfig.getDiscountPrice();
            //  减免金额
            derateAmount = originalAmount.subtract(orderAmount);

            //  订单明细
            OrderDetailVo orderDetailVo = new OrderDetailVo();
            //  vip服务配置Id
            orderDetailVo.setItemId(tradeVo.getItemId());
            orderDetailVo.setItemName("购买VIP" + vipServiceConfig.getName());
            orderDetailVo.setItemUrl(vipServiceConfig.getImageUrl());
            orderDetailVo.setItemPrice(orderAmount);

            orderDetailVoList.add(orderDetailVo);
            //  减免明细
            if (derateAmount.compareTo(BigDecimal.ZERO) != 0) {
                OrderDerateVo orderDerateVo = new OrderDerateVo();
                orderDerateVo.setDerateAmount(derateAmount);
                orderDerateVo.setDerateType(SystemConstant.ORDER_DERATE_VIP_SERVICE_DISCOUNT);
                orderDerateVoList.add(orderDerateVo);
            }
        }
        //  生成一个交易号。
        String tradeNo = UUID.randomUUID().toString().replaceAll("-", "");
        //  防止用户无刷新重复回退提交订单！
        //  tradeNo 存储到缓存. key不能重复
        String tradeNoKey = "user:trade:" + userId;
        //  将数据存储到缓存.
        this.redisTemplate.opsForValue().set(tradeNoKey, tradeNo, 10, TimeUnit.MINUTES);
        //  创建对象
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        //  赋值：
        orderInfoVo.setTradeNo(tradeNo);
        //  支付方式：默认或空
        //  orderInfoVo.setPayWay(SystemConstant.ORDER_PAY_WAY_WEIXIN);
        orderInfoVo.setPayWay("");
        //  购买类型
        orderInfoVo.setItemType(tradeVo.getItemType());
        //  赋值金额
        orderInfoVo.setOriginalAmount(originalAmount);
        orderInfoVo.setOrderAmount(orderAmount);
        orderInfoVo.setDerateAmount(derateAmount);
        orderInfoVo.setOrderDetailVoList(orderDetailVoList);
        orderInfoVo.setOrderDerateVoList(orderDerateVoList);
        //  时间戳，
        orderInfoVo.setTimestamp(SignHelper.getTimestamp());
        //  orderInfoVo--->Map
        Map map = JSON.parseObject(JSON.toJSONString(orderInfoVo), Map.class);
        String sign = SignHelper.getSign(map);
        //  签名：保证数据不会被篡改。
        orderInfoVo.setSign(sign);
        //  返回数据对象.
        return orderInfoVo;
    }
}
